package com.canaan.business.service.inOutStock.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.canaan.business.common.enums.basic.ContainerStatusEnum;
import com.canaan.business.common.enums.basic.WhetherEnum;
import com.canaan.business.common.enums.inOutStock.*;
import com.canaan.business.common.enums.quality.QualityTaskStatusEnum;
import com.canaan.business.common.enums.quality.QualityTypeEnum;
import com.canaan.business.common.enums.storehouse.BarcodeRecordStatusEnum;
import com.canaan.business.common.enums.storehouse.InOutStorageOperationEnum;
import com.canaan.business.common.enums.storehouse.StockQualityStatusEnum;
import com.canaan.business.common.enums.storehouse.StorehouseStockStatusEnum;
import com.canaan.business.domain.basic.Container;
import com.canaan.business.domain.basic.ContainerBarcode;
import com.canaan.business.domain.basic.WmsProduct;
import com.canaan.business.domain.basic.WmsStorehouseLocation;
import com.canaan.business.domain.bill.AdjustInBill;
import com.canaan.business.domain.bill.RefundProductBill;
import com.canaan.business.domain.bill.SalesRefundBill;
import com.canaan.business.domain.bill.ScrapProductBill;
import com.canaan.business.domain.inOutStock.*;
import com.canaan.business.domain.invoice.WmsProStockApply;
import com.canaan.business.domain.quality.ProductQualityMainTask;
import com.canaan.business.domain.storehouse.WmsBarcodeRecord;
import com.canaan.business.domain.storehouse.WmsInOutStorage;
import com.canaan.business.domain.storehouse.WmsStorehouseStock;
import com.canaan.business.domain.vo.YardageGoodsBarcodeVo;
import com.canaan.business.domain.vo.YardageGoodsTaskOrderConfirmVo;
import com.canaan.business.mapper.inOutStock.YardageGoodsTaskOrderMapper;
import com.canaan.business.service.basic.IContainerBarcodeService;
import com.canaan.business.service.basic.IContainerService;
import com.canaan.business.service.basic.IWmsProductService;
import com.canaan.business.service.basic.IWmsStorehouseLocationService;
import com.canaan.business.service.bill.IAdjustInBillService;
import com.canaan.business.service.bill.IRefundProductBillService;
import com.canaan.business.service.bill.ISalesRefundBillService;
import com.canaan.business.service.bill.IScrapProductBillService;
import com.canaan.business.service.inOutStock.IWmsInStockDetailOrderService;
import com.canaan.business.service.inOutStock.IWmsInStockOrderService;
import com.canaan.business.service.inOutStock.IYardageGoodsRecordService;
import com.canaan.business.service.inOutStock.IYardageGoodsTaskOrderService;
import com.canaan.business.service.invoice.IWmsProStockApplyService;
import com.canaan.business.service.quality.IProductQualityItemService;
import com.canaan.business.service.quality.IProductQualityMainTaskService;
import com.canaan.business.service.storehouse.IWmsBarcodeRecordService;
import com.canaan.business.service.storehouse.IWmsInOutStorageService;
import com.canaan.business.service.storehouse.IWmsStorehouseStockService;
import com.canaan.common.constant.PrefixConstants;
import com.canaan.common.exception.ServiceException;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.StringUtils;
import com.canaan.common.utils.TableNoUtil;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 码货任务单Service业务层处理
 *
 * @author ruoyi
 * @date 2023-01-30
 */
@Service
public class YardageGoodsTaskOrderServiceImpl implements IYardageGoodsTaskOrderService {
    @Resource
    private YardageGoodsTaskOrderMapper yardageGoodsTaskOrderMapper;

    @Autowired
    private IYardageGoodsRecordService yardageGoodsRecordService;
    @Resource
    private IWmsStorehouseStockService wmsStorehouseStockService;
    @Resource
    private IWmsInStockDetailOrderService wmsInStockDetailOrderService;
    @Resource
    private IWmsInStockOrderService wmsInStockOrderService;
    @Resource
    private IWmsProductService wmsProductService;
    @Resource
    private IWmsStorehouseLocationService wmsStorehouseLocationService;
    @Resource
    private IWmsProStockApplyService wmsProStockApplyService;
    @Resource
    private IRefundProductBillService refundProductBillService;
    @Resource
    private IScrapProductBillService scrapProductBillService;
    @Resource
    private ISalesRefundBillService salesRefundBillService;
    @Resource
    private IAdjustInBillService adjustInBillService;
    @Resource
    private IWmsInOutStorageService wmsInOutStorageService;
    @Resource
    private IWmsBarcodeRecordService wmsBarcodeRecordService;
    @Resource
    private IProductQualityMainTaskService productQualityMainTaskService;
    @Resource
    private IProductQualityItemService productQualityItemService;
    @Resource
    private IContainerService containerService;
    @Resource
    private IContainerBarcodeService containerBarcodeService;


    /**
     * 查询码货任务单
     *
     * @param id 码货任务单主键
     * @return 码货任务单
     */
    @Override
    public YardageGoodsTaskOrder selectYardageGoodsTaskOrderById(Long id) {
        return yardageGoodsTaskOrderMapper.selectYardageGoodsTaskOrderById(id);
    }

    /**
     * 查询码货任务单列表
     *
     * @param yardageGoodsTaskOrder 码货任务单
     * @return 码货任务单
     */
    @Override
    public List<YardageGoodsTaskOrder> selectYardageGoodsTaskOrderList(YardageGoodsTaskOrder yardageGoodsTaskOrder) {
        // 需要返回字段供PDA显示
        List<YardageGoodsTaskOrder> returnList = yardageGoodsTaskOrderMapper.selectYardageGoodsTaskOrderList(yardageGoodsTaskOrder);
        for (YardageGoodsTaskOrder goodsTaskOrder : returnList) {
            // 2023-03-15 需求，如果指定了库位，PDA显示库位，否则显示仓库
            if (StringUtils.isNotEmpty(goodsTaskOrder.getStorehouseLocationNo())){
                goodsTaskOrder.setPdaLocationLabel(goodsTaskOrder.getStorehouseLocationNo());
            }else {
                goodsTaskOrder.setPdaLocationLabel(goodsTaskOrder.getStorehouseNo());
            }
        }
        return returnList;
    }

    /**
     * 新增码货任务单
     *
     * @param yardageGoodsTaskOrder 码货任务单
     * @return 结果
     */
    @Override
    public int insertYardageGoodsTaskOrder(YardageGoodsTaskOrder yardageGoodsTaskOrder) {
        if (StringUtils.isEmpty(yardageGoodsTaskOrder.getNo())) {
            yardageGoodsTaskOrder.setNo(PrefixConstants.YARD+TableNoUtil.getNo(YardageGoodsTaskOrder.class));
        }
        yardageGoodsTaskOrder.setCreateBy(SecurityUtils.getUsername());
        yardageGoodsTaskOrder.setCreateTime(DateUtils.getNowDate());
        return yardageGoodsTaskOrderMapper.insertYardageGoodsTaskOrder(yardageGoodsTaskOrder);
    }

    /**
     * 批量新增码货任务单
     *
     * @param yardageGoodsTaskOrderList 码货任务单列表
     * @return 结果
     */
    @Override
    public int batchInsertYardageGoodsTaskOrder(List<YardageGoodsTaskOrder> yardageGoodsTaskOrderList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (YardageGoodsTaskOrder yardageGoodsTaskOrder : yardageGoodsTaskOrderList) {
            if (StringUtils.isEmpty(yardageGoodsTaskOrder.getNo())) {
                yardageGoodsTaskOrder.setNo(TableNoUtil.getNo(YardageGoodsTaskOrder.class));
            }
            yardageGoodsTaskOrder.setCreateBy(username);
            yardageGoodsTaskOrder.setCreateTime(currerTime);
        }
        int insertNum = 0;

        for (int i = 0; i < yardageGoodsTaskOrderList.size(); ) {
            int endIndex = i + 500;
            if (endIndex > yardageGoodsTaskOrderList.size()) {
                endIndex = yardageGoodsTaskOrderList.size();
            }
            insertNum = insertNum + yardageGoodsTaskOrderMapper.batchInsertYardageGoodsTaskOrder(yardageGoodsTaskOrderList.subList(i, endIndex));
            i = endIndex;
        }
        return insertNum;
    }

    /**
     * 修改码货任务单
     *
     * @param yardageGoodsTaskOrder 码货任务单
     * @return 结果
     */
    @Override
    public int updateYardageGoodsTaskOrder(YardageGoodsTaskOrder yardageGoodsTaskOrder) {
        yardageGoodsTaskOrder.setUpdateBy(SecurityUtils.getUsername());
        yardageGoodsTaskOrder.setUpdateTime(DateUtils.getNowDate());
        return yardageGoodsTaskOrderMapper.updateYardageGoodsTaskOrder(yardageGoodsTaskOrder);
    }

    /**
     * 批量修改码货任务单
     *
     * @param yardageGoodsTaskOrderList 码货任务单列表
     * @return 结果
     */
    @Override
    public int batchUpdateYardageGoodsTaskOrder(List<YardageGoodsTaskOrder> yardageGoodsTaskOrderList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (YardageGoodsTaskOrder yardageGoodsTaskOrder : yardageGoodsTaskOrderList) {
            yardageGoodsTaskOrder.setUpdateBy(username);
            yardageGoodsTaskOrder.setUpdateTime(currerTime);
        }
        int updateNum = 0;
        for (int i=0; i<yardageGoodsTaskOrderList.size();) {
            int endIndex = i+500;
            if (endIndex > yardageGoodsTaskOrderList.size()) {
                endIndex = yardageGoodsTaskOrderList.size();
            }
            updateNum = updateNum + yardageGoodsTaskOrderMapper.batchUpdateYardageGoodsTaskOrder(yardageGoodsTaskOrderList.subList(i, endIndex));
            i = endIndex;
        }
        return updateNum;
    }

    /**
     * 批量删除码货任务单
     *
     * @param ids 需要删除的码货任务单主键集合
     * @return 结果
     */
    @Override
    public int deleteYardageGoodsTaskOrderByIds(Long[] ids) {
        for (int i =0;i<ids.length;i++){
            YardageGoodsTaskOrder yardageGoodsTaskOrder = this.selectYardageGoodsTaskOrderById(ids[0]);
            if (yardageGoodsTaskOrder!=null){
                if (!YardageGoodsOrderStatusEnum.CREATE.getCode().equals(yardageGoodsTaskOrder.getOrderStatus())){
                    throw new ServiceException("码货单状态为新建才能删除");
                }
            }
        }
        return yardageGoodsTaskOrderMapper.deleteYardageGoodsTaskOrderByIds(ids);
    }

    /**
     * 删除码货任务单信息
     *
     * @param id 码货任务单主键
     * @return 结果
     */
    @Override
    public int deleteYardageGoodsTaskOrderById(Long id) {
        return yardageGoodsTaskOrderMapper.deleteYardageGoodsTaskOrderById(id);
    }

    /**
     * 查询码货任务单
     *
     * @param no 编号
     * @return 码货任务单
     */
    @Override
    public YardageGoodsTaskOrder selectYardageGoodsTaskOrderByNo(String no) {
        return yardageGoodsTaskOrderMapper.selectYardageGoodsTaskOrderByNo(no);
    }

    /**
     * 批量删除码货任务单
     *
     * @param nos 需要删除的编号集合
     * @return 结果
     */
    @Override
    public int deleteYardageGoodsTaskOrderByNos(String[] nos) {
        return yardageGoodsTaskOrderMapper.deleteYardageGoodsTaskOrderByNos(nos);
    }

    /**
     * 删除码货任务单信息
     *
     * @param no 编号
     * @return 结果
     */
    @Override
    public int deleteYardageGoodsTaskOrderByNo(String no) {
        return yardageGoodsTaskOrderMapper.deleteYardageGoodsTaskOrderByNo(no);
    }

    //出入库记录类型转换
    public Long inoutTypeConvert(Integer type) {
        if (InStockOrderTypeEnum.PRODUCTION.getCode() == type) {
            return InOutStockTypeEnum.PRODUCTION.getCode().longValue();
        } else if (InStockOrderTypeEnum.STORES_RETURNED.getCode() == type) {
            return InOutStockTypeEnum.STORES_RETURNED.getCode().longValue();
        } else if (InStockOrderTypeEnum.SCRAP.getCode() == type) {
            return InOutStockTypeEnum.SCRAP.getCode().longValue();
        } else if (InStockOrderTypeEnum.SALES_REFUND.getCode() == type) {
            return InOutStockTypeEnum.SALES_REFUND.getCode().longValue();
        } else if (InStockOrderTypeEnum.WAIT_INSPECTION.getCode() == type) {
            return InOutStockTypeEnum.WAIT_INSPECTION.getCode().longValue();
        } else if (InStockOrderTypeEnum.RECEIVING.getCode() == type) {
            return InOutStockTypeEnum.RECEIVING.getCode().longValue();
        } else if (InStockOrderTypeEnum.ALLOCATE.getCode() == type) {
            return InOutStockTypeEnum.ALLOCATE.getCode().longValue();
        } else {
            return InOutStockTypeEnum.OTHER_IN.getCode().longValue();
        }
    }

    /**
     *  完成码货
     * @param confirmVo
     * @param isComplete
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int confirmOrComplete(YardageGoodsTaskOrderConfirmVo confirmVo, Boolean isComplete) {
        if (confirmVo == null) {
            throw new ServiceException("数据为空");
        }
        YardageGoodsTaskOrder taskOrder = this.yardageGoodsTaskOrderMapper.selectYardageGoodsTaskOrderByNo(confirmVo.getNo());
        if (taskOrder == null) {
            throw new ServiceException("找不到码货任务");
        }
        List<YardageGoodsRecord> recordList = confirmVo.getYardageGoodsRecordList() == null ?
                Collections.emptyList() : confirmVo.getYardageGoodsRecordList();
        if (!isComplete && recordList.isEmpty()) {
            throw new ServiceException("码货记录不能为空");
        }
        //提取容器编号更新容器状态
        List<String> containerList = recordList.stream().map(YardageGoodsRecord::getContainerNo).distinct().collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(containerList)){
            containerList.stream().forEach(e->{
                this.updateContainerStatus(e);
            });
        }
        //如果是退料入库，销售退货入库 ，判断一下如果条码已经在库存里且库存的库位不等于当前扫描入库的库位,提示“该条码已绑定库位为：****
        if(InStockOrderTypeEnum.STORES_RETURNED.getCode().equals(taskOrder.getOrderType())
                || InStockOrderTypeEnum.SALES_REFUND.getCode().equals(taskOrder.getOrderType()) ){
            Map<String,YardageGoodsRecord> barcodeMap =  recordList.stream().filter(e -> StringUtils.isNotEmpty(e.getBarCode()))
                    .collect(Collectors.toMap(YardageGoodsRecord::getBarCode, e -> e, (v1,v2) -> v1));
            if(!barcodeMap.isEmpty()){
                WmsStorehouseStock storehouseStock = new WmsStorehouseStock();
                storehouseStock.setBarcodes(new ArrayList<>(barcodeMap.keySet()));
                List<WmsStorehouseStock> stockList = wmsStorehouseStockService.selectWmsStorehouseStockList(storehouseStock);
                for (WmsStorehouseStock stock : stockList) {
                    YardageGoodsRecord record = barcodeMap.get(stock.getBarcode());
                    if(record != null && !stock.getStorehouseLocationNo().equals(record.getStorehouseLocationNo())){
                        throw new ServiceException(record.getBarCode() + "条码已绑定库位为：" + stock.getStorehouseLocationNo());
                    }
                }
            }
        }
        List<String> inputLocationNos = recordList.stream().map(YardageGoodsRecord::getStorehouseLocationNo).distinct().collect(Collectors.toList());
        if(InStockOrderTypeEnum.WAIT_INSPECTION.getCode().equals(taskOrder.getOrderType())){
            //如果是待检单的走特别流程
            confirmVo.setYardageGoodsRecordList(recordList);
            return waitInspectionConfirmOrComplete(confirmVo, isComplete, taskOrder);
        }
        long number = recordList.stream().mapToLong(YardageGoodsRecord::getPickingQty).sum();
        long totalNumber = number + taskOrder.getActualQty();
        try {
            //获取入库单明细
            WmsInStockDetailOrder inStockDetailOrder  = wmsInStockDetailOrderService.selectWmsInStockDetailOrderById(taskOrder.getInOrderId());
            if (!recordList.isEmpty()) {
                //已码货
                if (taskOrder.getOrderQty() < number) {
                    throw new ServiceException("入库数量不能大于单据数量");
                }
                //插入码货记录
                for (YardageGoodsRecord yardageGoodsRecord : recordList) {
                    yardageGoodsRecord.setTaskNo(taskOrder.getNo());
                    if(StringUtils.isEmpty(yardageGoodsRecord.getProductNo())) {
                        yardageGoodsRecord.setProductNo(taskOrder.getProductNo());
                    }
                }
                yardageGoodsRecordService.batchInsertYardageGoodsRecord(recordList);
                WmsStorehouseLocation location = new WmsStorehouseLocation();
                location.setStorehouseNo(taskOrder.getStorehouseNo());
                List<WmsStorehouseLocation> locationList = wmsStorehouseLocationService.selectWmsStorehouseLocationList(location);
                Map<String, WmsStorehouseLocation>   locationMap = locationList.stream()
                        .collect(Collectors.toMap(WmsStorehouseLocation::getNo, e -> e));
                //整理和校验库位信息,如果入库单存在库位信息，判断库位是否正确
                if (StringUtils.isNotEmpty(taskOrder.getStorehouseLocationNo())){
                    for (String inputLocationNo : inputLocationNos) {
                        if (!inputLocationNo.equals(taskOrder.getStorehouseLocationNo())){
                            throw new ServiceException("该入库单已指定库位：" + taskOrder.getStorehouseLocationNo());
                        }
                    }
                }else {
                    Set<String> errorLocationNos = recordList.stream().map(YardageGoodsRecord::getStorehouseLocationNo)
                            .filter(e -> !locationMap.containsKey(e)).collect(Collectors.toSet());
                    if (!errorLocationNos.isEmpty()) {
                        throw new ServiceException(errorLocationNos + "库位不在指定仓库");
                    }
                }
                //获取和校验物料信息
                WmsProduct product = wmsProductService.selectWmsProductByProductNo(taskOrder.getProductNo());
                if (product == null) {
                    throw new ServiceException("物料不存在");
                }
                //处理库存信息
                this.buildStock(taskOrder,recordList,locationMap,product,inStockDetailOrder.getOrderNo());
            }
            //更新任务状态为已完成
            Date completeTime = isComplete ? new Date() : null;
            taskOrder.setOrderStatus(YardageGoodsOrderStatusEnum.IN_HAND.getCode());
            taskOrder.setCompleteTime(completeTime);
            taskOrder.setActualQty(totalNumber);
            this.updateYardageGoodsTaskOrder(taskOrder);
            //修改入库单和明细信息
            if (inStockDetailOrder!=null) {
                if (inStockDetailOrder.getActualQty()!=null){
                    inStockDetailOrder.setActualQty(inStockDetailOrder.getActualQty()+number);
                }else{
                    inStockDetailOrder.setActualQty(totalNumber);
                }
                inStockDetailOrder.setOrderDetailStatus(OutOrderStatusEnum.PICKING.getCode());
                this.wmsInStockDetailOrderService.updateWmsInStockDetailOrder(inStockDetailOrder);
                WmsInStockOrder inStockOrder = wmsInStockOrderService.selectWmsInStockOrderByNo(inStockDetailOrder.getOrderNo());
                if (inStockOrder != null) {
                    inStockOrder.setOrderStatus(InOrderStatusEnum.PICKING.getCode());
                    if (inStockOrder.getTotalActualQty()!=null){
                        inStockOrder.setTotalActualQty(inStockOrder.getTotalActualQty() + number);
                    }else{
                        inStockOrder.setTotalActualQty(inStockDetailOrder.getActualQty());
                    }
                    wmsInStockOrderService.updateWmsInStockOrder(inStockOrder);
                    if (isComplete) {
                        this.complete(taskOrder,recordList,null);
                    }
                }
            }
        } catch (Exception ex) {
            throw new ServiceException("操作失败哦：" + ex.getMessage());
        }
        return 1;
    }

    @Transactional(rollbackFor = Exception.class)
   public void updateContainerStatus(String containerNo){
       if(StringUtils.isNotEmpty(containerNo)){
           Container container = containerService.selectContainerByNo(containerNo);
           if (container != null){
               if (ContainerStatusEnum.IN_STOCK.getCode().equals(container.getStatus())){
                   throw new ServiceException("该容器已入库,不允许重复入库");
               }else{
                   container.setStatus(ContainerStatusEnum.IN_STOCK.getCode());
                   containerService.updateContainer(container);
               }
           }else{
               throw new ServiceException("该容器不存在");
           }
       }
   }
    /**
     * 处理库存信息
     */
    void buildStock(YardageGoodsTaskOrder taskOrder, List<YardageGoodsRecord> recordList, Map<String, WmsStorehouseLocation> locationMap, WmsProduct product, String bussinessNo){
        for (YardageGoodsRecord record : recordList) {
            //获取库区编号
            String storehouseAreaNo = locationMap.containsKey(record.getStorehouseLocationNo()) ?
                    locationMap.get(record.getStorehouseLocationNo()).getStorehouseAreaNo() : "";
            //获取条码
            WmsBarcodeRecord barcodeRecord = wmsBarcodeRecordService.getByBarcode(record.getBarCode());
            //获取容器
            ContainerBarcode containerBarcode = containerBarcodeService.getByBarcode(barcodeRecord.getBarCode());
            //入库记录初始化
            WmsInOutStorage inStorage = new WmsInOutStorage();
            inStorage.setProductNo(taskOrder.getProductNo());
            if (containerBarcode!=null){
                inStorage.setContainerNo(containerBarcode.getContainerNo());
            }
            inStorage.setProductName(product.getProductName());
            inStorage.setProductUnit(product.getCompany());
            inStorage.setStorehouseNo(taskOrder.getStorehouseNo());
            inStorage.setAreaNo(storehouseAreaNo);
            inStorage.setStorehouseLocationNo(record.getStorehouseLocationNo());
            inStorage.setBatchNo(barcodeRecord.getBatchNo());
            inStorage.setBarcode(record.getBarCode());
            inStorage.setQuantity(record.getPickingQty());
            inStorage.setRelNo(taskOrder.getRelOrderNo());
            inStorage.setBusinessNo(bussinessNo);
            inStorage.setType(this.inoutTypeConvert(taskOrder.getOrderType()));
            inStorage.setOperation(InOutStorageOperationEnum.IN.getCode());
            wmsInOutStorageService.insertWmsInOutStorage(inStorage);
            //将条码状态更新为已入库
            barcodeRecord.setStatus(BarcodeRecordStatusEnum.IN.getCode());
            wmsBarcodeRecordService.updateWmsBarcodeRecord(barcodeRecord);
        }
    }
    /**
     * 码货单完成 更新入库明细和入库单
     * @param
     */
    public void complete(YardageGoodsTaskOrder taskOrder, List<YardageGoodsRecord> recordList, Map<String, WmsStorehouseLocation> locationMap){
        taskOrder.setOrderStatus(YardageGoodsOrderStatusEnum.ACCOMPLISH.getCode());
        if (recordList.isEmpty()) {
            //完成有的时候没有记录列表
            YardageGoodsRecord recordParams = new YardageGoodsRecord();
            recordParams.setTaskNo(taskOrder.getNo());
            recordList = yardageGoodsRecordService.selectYardageGoodsRecordList(recordParams);
        }
        if(!recordList.isEmpty()){
            WmsBarcodeRecord barcodeRecord = wmsBarcodeRecordService.selectLastBarcode(recordList.get(0).getBarCode());
            taskOrder.setBatchNo(barcodeRecord != null ? barcodeRecord.getBatchNo() : null);
        }
        this.updateYardageGoodsTaskOrder(taskOrder);
        Date completeTime = new Date();
        //获取入库单明细
        WmsInStockDetailOrder inStockDetailOrder = this.wmsInStockDetailOrderService.selectWmsInStockDetailOrderById(taskOrder.getInOrderId());
        if (inStockDetailOrder!=null){
            //获取入库单
            WmsInStockOrder inStockOrder = this.wmsInStockOrderService.selectWmsInStockOrderByNo(inStockDetailOrder.getOrderNo());
            if (inStockOrder!=null){
                //判断是否所有码货单都已完成
                List<YardageGoodsTaskOrder> yardageGoodsTaskOrderList = this.selectByInOrderId(taskOrder.getInOrderId());
                if (CollectionUtil.isNotEmpty(yardageGoodsTaskOrderList)){
                    Long yeardCount = yardageGoodsTaskOrderList.stream().filter(e->e.getOrderStatus().equals(OutOrderStatusEnum.ACCOMPLISH.getCode())).count();
                    if (yeardCount.intValue() == yardageGoodsTaskOrderList.size()){
                        inStockDetailOrder.setOrderDetailStatus(OutOrderStatusEnum.ACCOMPLISH.getCode());
                        wmsInStockDetailOrderService.updateWmsInStockDetailOrder(inStockDetailOrder);
                        //判断是否是收货入库
                        if(inStockOrder.getOrderType()==InStockOrderTypeEnum.RECEIVING.getCode()){
                            //处理待检的物料
                            execWaitProduct(inStockDetailOrder.getId());
                        }
                    }
                }
                //完成校验和处理
                WmsInStockDetailOrder query = new WmsInStockDetailOrder();
                query.setOrderNo(inStockDetailOrder.getOrderNo());
                List<WmsInStockDetailOrder> detailOrders = wmsInStockDetailOrderService.selectWmsInStockDetailOrderList(query);
                boolean isAllComplete = detailOrders.stream()
                        .allMatch(e -> e.getOrderDetailStatus() != null
                                && OutOrderStatusEnum.ACCOMPLISH.getCode().equals(e.getOrderDetailStatus()));
                if (isAllComplete) {
                    //完成就修改入库单的状态和填入完成时间
                    inStockOrder.setCompleteTime(completeTime);
                    inStockOrder.setOrderStatus(InOrderStatusEnum.ACCOMPLISH.getCode());
                    wmsInStockOrderService.updateWmsInStockOrder(inStockOrder);
                    if(!InStockOrderTypeEnum.WAIT_INSPECTION.getCode().equals(taskOrder.getOrderType())) {
                        //如果入库单变成完成状态，那对应的来源单据也要变成完成状态，除了收货、待检和其他
                        if(InOrderStatusEnum.ACCOMPLISH.getCode().equals(inStockOrder.getOrderStatus())) {
                            if (StringUtils.isNotEmpty(inStockOrder.getRelOrderNo())
                                    && InStockOrderTypeEnum.PRODUCTION.getCode().equals(inStockOrder.getOrderType())) {
                                //生产入库单
                                WmsProStockApply apply = wmsProStockApplyService.selectWmsProStockApplyByNo(inStockOrder.getRelOrderNo());
                                if (apply != null) {
                                    apply.setOrderStatus(InOrderStatusEnum.ACCOMPLISH.getCode());
                                    apply.setCompleteTime(new Date());
                                    apply.setTotalActualQty(inStockOrder.getTotalActualQty());
                                    wmsProStockApplyService.updateWmsProStockApply(apply);
                                }
                            } else if (StringUtils.isNotEmpty(inStockOrder.getRelOrderNo())
                                    && InStockOrderTypeEnum.STORES_RETURNED.getCode().equals(inStockOrder.getOrderType())) {
                                //退料单
                                RefundProductBill bill = refundProductBillService.selectRefundProductBillByNo(inStockOrder.getRelOrderNo());
                                if (bill != null) {
                                    bill.setStatus(InOrderStatusEnum.ACCOMPLISH.getCode());
                                    bill.setCompleteTime(new Date());
                                    refundProductBillService.updateRefundProductBill(bill);
                                }
                            } else if (StringUtils.isNotEmpty(inStockOrder.getRelOrderNo())
                                    && InStockOrderTypeEnum.SCRAP.getCode().equals(inStockOrder.getOrderType())) {
                                //报废单
                                ScrapProductBill bill = scrapProductBillService.selectScrapProductBillByNo(inStockOrder.getRelOrderNo());
                                if (bill != null) {
                                    bill.setStatus(OutOrderStatusEnum.ACCOMPLISH.getCode());
                                    bill.setCompleteTime(new Date());
                                    scrapProductBillService.updateScrapProductBill(bill);
                                }
                            } else if (StringUtils.isNotEmpty(inStockOrder.getRelOrderNo())
                                    && InStockOrderTypeEnum.SALES_REFUND.getCode().equals(inStockOrder.getOrderType())) {
                                //销售退货单
                                SalesRefundBill bill = salesRefundBillService.selectSalesRefundBillByNo(inStockOrder.getRelOrderNo());
                                if (bill != null) {
                                    bill.setStatus(InOrderStatusEnum.ACCOMPLISH.getCode());
                                    bill.setCompleteTime(new Date());
                                    salesRefundBillService.updateSalesRefundBill(bill);
                                }
                            } else if (StringUtils.isNotEmpty(inStockOrder.getRelOrderNo())
                                    && InStockOrderTypeEnum.ALLOCATE.getCode().equals(inStockOrder.getOrderType())) {
                                //调拨入库
                                AdjustInBill bill = adjustInBillService.selectAdjustInBillByNo(inStockOrder.getRelOrderNo());
                                if (bill != null) {
                                    bill.setStatus(InOrderStatusEnum.ACCOMPLISH.getCode());
                                    bill.setCompleteTime(new Date());
                                    adjustInBillService.updateAdjustInBill(bill);
                                }
                            }
                        }
                    }else{
                        //判断是否完成,完成就走待检的处理流程
                            List<ProductQualityMainTask> productQualityMainTaskList = new ArrayList<>();
                            for (WmsInStockDetailOrder order : detailOrders) {
                                //是否来料检
                                if(this.productQualityItemService.isIqc(order.getProductNo())){
                                    ProductQualityMainTask productQualityMainTask = new ProductQualityMainTask();
                                    productQualityMainTask.setProductNo(order.getProductNo());
                                    productQualityMainTask.setProductName(order.getProductName());
                                    productQualityMainTask.setTotalQuantity(BigDecimal.valueOf(order.getActualQty()));
                                    productQualityMainTask.setInspectedQuantity(BigDecimal.ZERO);
                                    productQualityMainTask.setSourceNo(inStockOrder.getRelOrderNo());
                                    productQualityMainTask.setQualityType(QualityTypeEnum.IQC.getCode());
                                    productQualityMainTask.setStatus(QualityTaskStatusEnum.WAIT.getCode());
                                    productQualityMainTask.setStorehouseNo(order.getStorehouseNo());
                                    productQualityMainTask.setStorehouseName(order.getStorehouseName());
                                    productQualityMainTask.setStorehouseLocationNo(order.getStorehouseLocationNo());
                                    productQualityMainTask.setStorehouseLocationName(order.getStorehouseLocationName());
                                    productQualityMainTask.setBusinessNo(order.getOrderNo());
                                    productQualityMainTask.setInOrderDetailId(order.getId());
                                    productQualityMainTaskList.add(productQualityMainTask);
                                }
                            }
                            productQualityMainTaskService.batchInsertProductQualityMainTask(productQualityMainTaskList);
                            //处理待检仓库存
                            this.buildDjcStock(detailOrders,productQualityMainTaskList,locationMap,taskOrder,inStockOrder);

                        }
                }
            }
        }

    }

    /**
     * 处理待检仓库存
     * @param detailOrders
     * @param productQualityMainTaskList
     * @param locationMap
     * @param taskOrder
     * @param inStockOrder
     */
    public void buildDjcStock(List<WmsInStockDetailOrder>  detailOrders,List<ProductQualityMainTask> productQualityMainTaskList, Map<String, WmsStorehouseLocation> locationMap,YardageGoodsTaskOrder taskOrder, WmsInStockOrder inStockOrder){
        //处理库存信息，通过码货任务编号列表查询
        List<String> yardageGoodsOrderNos = Lists.newArrayList();
        for (WmsInStockDetailOrder item: detailOrders){
            List<YardageGoodsTaskOrder> yardageGoodsTaskOrderList = this.selectByInOrderId(item.getId());
            yardageGoodsOrderNos.addAll(yardageGoodsTaskOrderList.stream().map(YardageGoodsTaskOrder::getNo).collect(Collectors.toList()));
        }
        YardageGoodsRecord recordParams = new YardageGoodsRecord();
        recordParams.setTaskNos(yardageGoodsOrderNos);
        List<YardageGoodsRecord> recordList = yardageGoodsRecordService.selectYardageGoodsRecordList(recordParams);
        Map<String, String> qualityNoMap = productQualityMainTaskList.stream()
                .collect(Collectors.toMap(ProductQualityMainTask::getProductNo, ProductQualityMainTask::getNo));
        for (YardageGoodsRecord record : recordList) {
            //获取和校验物料信息
            WmsProduct product = wmsProductService.selectWmsProductByProductNo(record.getProductNo());
            if (product == null) {
                throw new ServiceException("物料不存在");
            }
            WmsStorehouseLocation location = wmsStorehouseLocationService.selectWmsStorehouseLocationByNo(record.getStorehouseLocationNo());
            //获取库区编号
            String storehouseAreaNo = location==null?"" : location.getStorehouseAreaNo();
            String storehouseNo = location==null?"" : location.getStorehouseNo();
            //获取条码
            WmsBarcodeRecord barcodeRecord = wmsBarcodeRecordService.getByBarcode(record.getBarCode());
            //入库记录初始化
            WmsInOutStorage inStorage = new WmsInOutStorage();
            inStorage.setProductNo(product.getProductNo());
            inStorage.setProductName(product.getProductName());
            inStorage.setProductUnit(product.getCompany());

            inStorage.setStorehouseNo(storehouseNo);
            inStorage.setAreaNo(storehouseAreaNo);
            inStorage.setStorehouseLocationNo(record.getStorehouseLocationNo());

            inStorage.setBatchNo(barcodeRecord.getBatchNo());
            inStorage.setBarcode(record.getBarCode());
            inStorage.setQuantity(record.getPickingQty());
            inStorage.setRelNo(taskOrder.getRelOrderNo());
            inStorage.setBusinessNo(inStockOrder.getNo());
            inStorage.setType(this.inoutTypeConvert(taskOrder.getOrderType()));
            inStorage.setOperation(InOutStorageOperationEnum.IN.getCode());
            inStorage.setProductQualityMainTaskNo(qualityNoMap.get(barcodeRecord.getProductNo()));
            wmsInOutStorageService.insertWmsInOutStorage(inStorage);
            //将条码状态更新为已入库
            barcodeRecord.setStatus(BarcodeRecordStatusEnum.IN.getCode());
            wmsBarcodeRecordService.updateWmsBarcodeRecord(barcodeRecord);
        }
    }
    @Override
    public List<YardageGoodsTaskOrder> selectByInOrderId(Long inOrderId) {
        YardageGoodsTaskOrder query = new YardageGoodsTaskOrder();
        query.setInOrderId(inOrderId);
        return this.selectYardageGoodsTaskOrderList(query);
    }

    /**
     * 待检的确认或完成
     * @param confirmVo     请求参数
     * @param isComplete    是否完成
     * @param taskOrder     码货单信息
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int waitInspectionConfirmOrComplete(YardageGoodsTaskOrderConfirmVo confirmVo, Boolean isComplete,YardageGoodsTaskOrder taskOrder) {
        List<YardageGoodsRecord> recordList = confirmVo.getYardageGoodsRecordList();
        long number = recordList.stream().mapToLong(YardageGoodsRecord::getPickingQty).sum();
        long totalNumber = number + taskOrder.getActualQty();
        try {
            //修改入库单和明细信息
            WmsInStockDetailOrder inStockDetailOrder = this.wmsInStockDetailOrderService.selectWmsInStockDetailOrderById(taskOrder.getInOrderId());
            Map<String, WmsStorehouseLocation> locationMap = new LinkedHashMap<>();
            if (!recordList.isEmpty()) {
                //已码货
                if (taskOrder.getOrderQty() < number) {
                    throw new ServiceException("入库数量不能大于单据数量");
                }
                //插入码货记录
                for (YardageGoodsRecord yardageGoodsRecord : recordList) {
                    yardageGoodsRecord.setTaskNo(taskOrder.getNo());
                    if(StringUtils.isEmpty(yardageGoodsRecord.getProductNo())) {
                        yardageGoodsRecord.setProductNo(taskOrder.getProductNo());
                    }
                }
                yardageGoodsRecordService.batchInsertYardageGoodsRecord(recordList);
                WmsStorehouseLocation location = new WmsStorehouseLocation();
                location.setStorehouseNo(taskOrder.getStorehouseNo());
                location.setNo(taskOrder.getStorehouseLocationNo());
                List<WmsStorehouseLocation> locationList = wmsStorehouseLocationService.selectWmsStorehouseLocationList(location);
                locationMap = locationList.stream().collect(Collectors.toMap(WmsStorehouseLocation::getNo, e -> e));
                Set<String> locationMapKeySet = locationMap.keySet();
                //整理和校验库位信息 如果入库单存在库位信息，判断库位是否正确
                List<String> inputLocationNos = recordList.stream().map(YardageGoodsRecord::getStorehouseLocationNo).distinct().collect(Collectors.toList());
                if (StringUtils.isNotEmpty(taskOrder.getStorehouseLocationNo())){
                    for (String inputLocationNo : inputLocationNos) {
                        if (!inputLocationNo.equals(taskOrder.getStorehouseLocationNo())){
                            throw new ServiceException("该入库单已指定库位：" + taskOrder.getStorehouseLocationNo());
                        }
                    }
                }else {
                    Set<String> errorLocationNos = recordList.stream().map(YardageGoodsRecord::getStorehouseLocationNo)
                            .filter(e -> !locationMapKeySet.contains(e)).collect(Collectors.toSet());
                    if (!errorLocationNos.isEmpty()) {
                        throw new ServiceException(errorLocationNos + "库位不在指定仓库内");
                    }
                }
                //获取和校验物料信息
                WmsProduct product = wmsProductService.selectWmsProductByProductNo(taskOrder.getProductNo());
                if (product == null) {
                    throw new ServiceException("物料不存在");
                }
            }
            //更新任务状态为已完成
            Date completeTime = isComplete ? new Date() : null;
            taskOrder.setOrderStatus(YardageGoodsOrderStatusEnum.IN_HAND.getCode());
            taskOrder.setCompleteTime(completeTime);
            taskOrder.setActualQty(totalNumber);
            this.updateYardageGoodsTaskOrder(taskOrder);

            if (inStockDetailOrder!=null) {
                if (inStockDetailOrder.getActualQty()!=null){
                    inStockDetailOrder.setActualQty(inStockDetailOrder.getActualQty()+number);
                }else{
                    inStockDetailOrder.setActualQty(taskOrder.getActualQty());
                }
                wmsInStockDetailOrderService.updateWmsInStockDetailOrder(inStockDetailOrder);
                WmsInStockOrder inStockOrder = wmsInStockOrderService.selectWmsInStockOrderByNo(inStockDetailOrder.getOrderNo());
                if (inStockOrder != null) {
                    inStockOrder.setOrderStatus(InOrderStatusEnum.PICKING.getCode());
                    if (inStockOrder.getTotalActualQty()!=null){
                        inStockOrder.setTotalActualQty(inStockOrder.getTotalActualQty() + number);
                    }else{
                        inStockOrder.setTotalActualQty(inStockDetailOrder.getActualQty());
                    }
                    wmsInStockOrderService.updateWmsInStockOrder(inStockOrder);
                    if (isComplete) {
                        this.complete(taskOrder,recordList,locationMap);
                    }
                }
            }
        } catch (Exception ex) {
            throw new ServiceException("操作失败哦：" + ex.getMessage());
        }
        return 1;
    }

    public void execWaitProduct(Long orderDetailId){
        WmsInStockDetailOrder inStockDetailOrder = this.wmsInStockDetailOrderService.selectWmsInStockDetailOrderById(orderDetailId);
        if (inStockDetailOrder.getWhetherWaitProduct()!=null){
            //是否生成来料任务
            if (inStockDetailOrder.getWhetherWaitProduct()== WhetherEnum.Y.getCode().longValue()){
                //获取所有条码数据，根据条码更新库存
                List<YardageGoodsBarcodeVo> barcodeVoList = this.yardageGoodsRecordService.selectBarcodeByInOrderId(orderDetailId);
                if(CollectionUtil.isNotEmpty(barcodeVoList)){
                    List<String> barcodes = barcodeVoList.stream().map(YardageGoodsBarcodeVo::getBarcode).collect(Collectors.toList());
                    List<WmsStorehouseStock> storehouseStockList = this.wmsStorehouseStockService.getListByBarcodes(barcodes);
                    if (CollectionUtil.isNotEmpty(storehouseStockList)){
                        //获取总库存数量
                        Long totalQry = storehouseStockList.stream().collect(Collectors.summingLong(WmsStorehouseStock::getQty));
                        //创建质检任务
                        ProductQualityMainTask productQualityMainTask = new ProductQualityMainTask();
                        productQualityMainTask.setProductNo(inStockDetailOrder.getProductNo());
                        productQualityMainTask.setProductName(inStockDetailOrder.getProductName());
                        productQualityMainTask.setTotalQuantity(BigDecimal.valueOf(totalQry));
                        productQualityMainTask.setInspectedQuantity(BigDecimal.ZERO);
                        WmsInStockOrder inStockOrder = this.wmsInStockOrderService.selectWmsInStockOrderByNo(inStockDetailOrder.getOrderNo());
                        if (inStockOrder!=null){
                            productQualityMainTask.setSourceNo(inStockOrder.getRelOrderNo());
                        }
                        productQualityMainTask.setQualityType(QualityTypeEnum.IQC.getCode());
                        productQualityMainTask.setStatus(QualityTaskStatusEnum.WAIT.getCode());
                        productQualityMainTask.setStorehouseNo(inStockDetailOrder.getStorehouseNo());
                        productQualityMainTask.setStorehouseName(inStockDetailOrder.getStorehouseName());
                        productQualityMainTask.setStorehouseLocationNo(inStockDetailOrder.getStorehouseLocationNo());
                        productQualityMainTask.setStorehouseLocationName(inStockDetailOrder.getStorehouseLocationName());
                        productQualityMainTask.setBusinessNo(inStockDetailOrder.getOrderNo());
                        productQualityMainTask.setInOrderDetailId(inStockDetailOrder.getId());
                        this.productQualityMainTaskService.insertProductQualityMainTask(productQualityMainTask);
                        String qualityTaskNo = productQualityMainTask.getNo();
                        //更新库存
                        storehouseStockList.stream().forEach(e->{
                            e.setStatus(StorehouseStockStatusEnum.FREEZE.getCode());
                            e.setQualityStatus(StockQualityStatusEnum.UNCHECKED.getCode());
                            e.setQualityTaskNo(qualityTaskNo);
                        });
                        this.wmsStorehouseStockService.batchUpdateWmsStorehouseStock(storehouseStockList);
                    }
                }
            }
        }

    }
}
